/*
 * $Id: item.c 489 2008-05-13 06:29:08Z jasta $
 *
 * Copyright (C) 2008 Josh Guilfoyle <jasta@devtcg.org>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */

#include "main.h"

#include <sqlite3.h>

#include <libsyncml/syncml.h>
#include <libsyncml/sml_ds_server.h>

#include "session.h"

/*****************************************************************************/

/* GENERAL */
#define ITEM_FIELD_NAME         "N"

#define ITEM_FIELD_GENRE        "GENRE"
#define ITEM_FIELD_DISCOVERY    "DISCOVERY"
#define ITEM_FIELD_MBID         "MBID"

/* ARTIST */
#define ITEM_FIELD_PHOTO        "PHOTO"

/* ALBUM */
#define ITEM_FIELD_ARTWORK      "ARTWORK"
#define ITEM_FIELD_RELEASE      "RELEASE"

/* ALBUM or SONG */
#define ITEM_FIELD_ARTIST       "ARTIST"
#define ITEM_FIELD_ARTIST_GUID  "ARTIST_GUID"

/* SONG */
#define ITEM_FIELD_CONTENT      "CONTENT"
#define ITEM_FIELD_ALBUM        "ALBUM"
#define ITEM_FIELD_ALBUM_GUID   "ALBUM_GUID"
#define ITEM_FIELD_LENGTH       "LENGTH"
#define ITEM_FIELD_TRACK        "TRACK"
#define ITEM_FIELD_SIZE         "SIZE"

/*****************************************************************************/

static void add_data_line(GString *str, const char *label, const char *escaped)
{
	g_string_append(str, label);
	g_string_append_c(str, ':');
	g_string_append(str, escaped);
	g_string_append_c(str, '\n');
}

static void add_data_line_binary(GString *str, const char *label,
  const unsigned char *data, size_t len)
{
	gchar *b64;

	assert(data != NULL);
	assert(len > 0);

	b64 = g_base64_encode(data, len);
	assert(b64 != NULL);

	add_data_line(str, label, b64);
	g_free(b64);
}

static void add_data_line_unescaped(GString *str, const char *label,
  const char *unescaped)
{
#if 0
	char *escaped;

	escaped = g_markup_escape_text(unescaped, -1);
	add_data_line(str, label, escaped);
	g_free(escaped);
#endif

	add_data_line(str, label, unescaped);
}

/*****************************************************************************/

/*
 * Creates an item record for an application/x-fivedb-artist record.
 */
void item_set_artist_data(FiveChange *chg, sqlite3_stmt *stmt, int col)
{
	GString *data;
	int coln;

	assert(chg != NULL);
	assert(stmt != NULL);
	assert(col >= 0);

	coln = sqlite3_column_count(stmt);
	assert(coln > col);

	data = g_string_new(NULL);
	assert(data != NULL);

	for (; col < coln; col++)
	{
		const char *colname;
		const char *colvalue;
		gboolean is_null;

		colname = sqlite3_column_origin_name(stmt, col);
		assert(colname != NULL);

#if 0
		if (strcmp(colname, "photo_thumb") == 0)
		{
			const void *colblob = sqlite3_column_blob(stmt, col);
			int colbytes = sqlite3_column_bytes(stmt, col);

			if (colbytes > 0)
			{
				assert(colblob != NULL);
				add_data_line_binary(data, ITEM_FIELD_PHOTO, colblob, (size_t)colbytes);
			}

			continue;
		}
#endif

		colvalue = sqlite3_column_text(stmt, col);

		if (strcmp(colname, "name") == 0)
		{
			assert(colvalue != NULL);
			add_data_line_unescaped(data, ITEM_FIELD_NAME, colvalue);
		}
		else if (strcmp(colname, "genre") == 0)
		{
			if (colvalue != NULL)
				add_data_line_unescaped(data, ITEM_FIELD_GENRE, colvalue);
		}
		else if (strcmp(colname, "discovery_date") == 0)
		{
			if (colvalue != NULL)
				add_data_line(data, ITEM_FIELD_DISCOVERY, colvalue);
		}
		else if (strcmp(colname, "mbid") == 0)
		{
			if (colvalue != NULL)
				add_data_line(data, ITEM_FIELD_MBID, colvalue);
		}
	}

	chg->datasz = data->len;
	chg->data = g_string_free(data, FALSE);
}

/*
 * Creates an item record for an application/x-fivedb-album record.
 *
 * Can specify an extra column to contain the device-local id for the
 * artist field.
 */
void item_set_album_data(FiveChange *chg, int artist_luid_col,
  sqlite3_stmt *stmt, int col)
{
	GString *data;
	int coln;

	assert(chg != NULL);
	assert(stmt != NULL);
	assert(col >= 0);

	coln = sqlite3_column_count(stmt);
	assert(coln > col);

	data = g_string_new(NULL);
	assert(data != NULL);

	if (artist_luid_col >= 0)
	{
		if (sqlite3_column_type(stmt, artist_luid_col) != SQLITE_NULL)
			add_data_line(data, ITEM_FIELD_ARTIST, sqlite3_column_text(stmt, artist_luid_col));
	}

	for (; col < coln; col++)
	{
		const char *colname;
		const char *colvalue;
		gboolean is_null;

		colname = sqlite3_column_origin_name(stmt, col);
		assert(colname != NULL);

#if 0
		if (strcmp(colname, "artwork_thumb") == 0)
		{
			const void *colblob = sqlite3_column_blob(stmt, col);
			int colbytes = sqlite3_column_bytes(stmt, col);

			if (colbytes > 0)
			{
				assert(colblob != NULL);
				add_data_line_binary(data, ITEM_FIELD_ARTWORK, colblob, (size_t)colbytes);
			}

			continue;
		}
#endif

		colvalue = sqlite3_column_text(stmt, col);

		if (strcmp(colname, "name") == 0)
		{
			assert(colvalue != NULL);
			add_data_line_unescaped(data, ITEM_FIELD_NAME, colvalue);
		}
		else if (strcmp(colname, "genre") == 0)
		{
			if (colvalue != NULL)
				add_data_line_unescaped(data, ITEM_FIELD_GENRE, colvalue);
		}
		else if (strcmp(colname, "discovery_date") == 0)
		{
			if (colvalue != NULL)
				add_data_line(data, ITEM_FIELD_DISCOVERY, colvalue);
		}
		else if (strcmp(colname, "release") == 0)
		{
			if (colvalue != NULL)
				add_data_line(data, ITEM_FIELD_RELEASE, colvalue);
		}
		else if (strcmp(colname, "artist_id") == 0)
		{
			assert(colvalue != NULL);
			add_data_line(data, ITEM_FIELD_ARTIST_GUID, colvalue);
		}
		else if (strcmp(colname, "mbid") == 0)
		{
			if (colvalue != NULL)
				add_data_line(data, ITEM_FIELD_MBID, colvalue);
		}
	}

	chg->datasz = data->len;
	chg->data = g_string_free(data, FALSE);
}

/*
 * Creates an item record for an application/x-fivedb-song record.
 *
 * Can specify extra columns to contain the device-local id for the
 * artist and album fields.
 */
void item_set_song_data(FiveChange *chg,
  int artist_luid_col, int album_luid_col, sqlite3_stmt *stmt, int col)
{
	GString *data;
	int coln;

	assert(chg != NULL);
	assert(stmt != NULL);
	assert(col >= 0);

	coln = sqlite3_column_count(stmt);
	assert(coln > col);

	data = g_string_new(NULL);
	assert(data != NULL);

	if (artist_luid_col >= 0)
	{
		if (sqlite3_column_type(stmt, artist_luid_col) != SQLITE_NULL)
			add_data_line(data, ITEM_FIELD_ARTIST, sqlite3_column_text(stmt, artist_luid_col));
	}

	if (album_luid_col >= 0)
	{
		if (sqlite3_column_type(stmt, album_luid_col) != SQLITE_NULL)
			add_data_line(data, ITEM_FIELD_ALBUM, sqlite3_column_text(stmt, album_luid_col));
	}

	for (; col < coln; col++)
	{
		const char *colname;
		const char *colvalue;
		gboolean is_null;

		colname = sqlite3_column_origin_name(stmt, col);
		assert(colname != NULL);

		colvalue = sqlite3_column_text(stmt, col);

		if (strcmp(colname, "title") == 0)
		{
			assert(colvalue != NULL);
			add_data_line_unescaped(data, ITEM_FIELD_NAME, colvalue);
		}
		else if (strcmp(colname, "_id") == 0)
		{
			assert(colvalue != NULL);
			add_data_line(data, ITEM_FIELD_CONTENT, colvalue);
		}
		else if (strcmp(colname, "genre") == 0)
		{
			if (colvalue != NULL)
				add_data_line_unescaped(data, ITEM_FIELD_GENRE, colvalue);
		}
		else if (strcmp(colname, "discovery_date") == 0)
		{
			if (colvalue != NULL)
				add_data_line(data, ITEM_FIELD_DISCOVERY, colvalue);
		}
		else if (strcmp(colname, "artist_id") == 0)
		{
			assert(colvalue != NULL);
			add_data_line(data, ITEM_FIELD_ARTIST_GUID, colvalue);
		}
		else if (strcmp(colname, "artist_luid") == 0)
		{
			if (colvalue != NULL)
				add_data_line(data, ITEM_FIELD_ARTIST, colvalue);
		}
		else if (strcmp(colname, "album_id") == 0)
		{
			if (colvalue != NULL)
				add_data_line(data, ITEM_FIELD_ALBUM_GUID, colvalue);
		}
		else if (strcmp(colname, "album_luid") == 0)
		{
			if (colvalue != NULL)
				add_data_line(data, ITEM_FIELD_ALBUM, colvalue);
		}
		else if (strcmp(colname, "length") == 0)
		{
			assert(colvalue != NULL);
			add_data_line(data, ITEM_FIELD_LENGTH, colvalue);
		}
		else if (strcmp(colname, "track") == 0)
		{
			if (colvalue != NULL)
				add_data_line(data, ITEM_FIELD_TRACK, colvalue);
		}
		else if (strcmp(colname, "size") == 0)
		{
			assert(colvalue != NULL);
			add_data_line(data, ITEM_FIELD_SIZE, colvalue);
		}
		else if (strcmp(colname, "mbid") == 0)
		{
			if (colvalue != NULL)
				add_data_line(data, ITEM_FIELD_MBID, colvalue);
		}
	}

	chg->datasz = data->len;
	chg->data = g_string_free(data, FALSE);
}
